﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartSpace.Core
{
    public partial class CoreService : ICoreService
    {
        public bool SavePage(Page page)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                PageTemplate template = page.Template;
                page.Template = null;

                if (context.Set<Page>().Where(p => p.Id == page.Id)
                    .Select(p => p.Id).SingleOrDefault() == default(Guid))
                {
                    context.Set<Page>().Add(page);

                    Logger.Info("core", string.Format("add privilege for page {0}({1})", page.Code, page.Id));

                    Privilege privilege = new Privilege();
                    privilege.Id = Guid.NewGuid();
                    privilege.SiteId = page.SiteId;
                    privilege.Code = string.Format("{0}_{1}", page.Type.ToUpper(), page.Code.ToUpper());
                    privilege.SourceId = page.Id;
                    privilege.Type = "PAGE";
                    privilege.Caption = page.Caption;
                    privilege.Description = page.Caption;
                    EntityRepository.Save(privilege, context);
                }
                else
                {
                    if (context.Set<Page>().Where(p => p.Code == page.Code)
                       .Select(p => p.Id).SingleOrDefault() == default(Guid))
                    {
                        return false;
                    }

                    context.Entry(page).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    page.Template = template;
                    return true;
                }
                page.Template = template;
                return false;
            }
        }

        public Page GetPage(Guid applicationId, Guid id)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<Page>()
                    .Include("Template")
                    .Where(p => p.Id == id && p.SiteId == applicationId).SingleOrDefault();
            }
        }

        public Page GetPage(Guid applicationId, string name)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<Page>()
                    .Include("Template")
                    .Where(p => p.Code == name && p.SiteId == applicationId).SingleOrDefault();
            }
        }

        public PagedList<Page> GetPages(Guid applicationId, int start, int limit)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                PagedList<Page> pagedList = new PagedList<Page>();

                List<Page> pages = context.Set<Page>()
                    .Where(p=>p.SiteId == applicationId)
                    .OrderBy(p => p.Code)
                    .Take(limit)
                    .Skip(start).ToList();
                int total = context.Set<Page>().Where(p => p.SiteId == applicationId).OrderBy(p => p.Code).Count();
                pagedList.AddRange(pages);

                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = total;

                return pagedList;
            }
        }

        public bool SavePageContent(PageContent personalization)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                if (context.Set<PageContent>().Where(p => p.Id == personalization.Id)
                    .Select(p => p.Id).SingleOrDefault() == default(Guid))
                {
                    context.Set<PageContent>().Add(personalization);
                }
                else
                {
                    if (context.Set<PageContent>().Where(p => p.PageId == personalization.PageId)
                       .Select(p => p.Id).SingleOrDefault() == default(Guid))
                    {
                        return false;
                    }

                    context.Entry(personalization).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public ServiceResult DeletePageContent(Guid siteId, Guid pageId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                PageContent content = context.Set<PageContent>().Where(p => p.PageId == pageId && p.SiteId == siteId)
                    .SingleOrDefault();

                if (content != null)
                {
                    context.Entry(content).State = System.Data.Entity.EntityState.Deleted;

                    if (context.SaveChanges() > 0)
                    {
                        return new ServiceResult(true);
                    }
                }
                return new ServiceResult(false);
            }
        }

        public PageContent GetPageContent(Guid applicationId, Guid pageId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<PageContent>().Where(p => p.PageId == pageId && p.SiteId == applicationId)
                    .SingleOrDefault();
            }
        }

        public PageContent GetPagePersonalization(Guid applicationId, string name)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<PageContent>()
                    .Join(context.Set<Page>().Where(p => p.Code == name && p.SiteId == applicationId),
                        l => l.PageId,
                        r => r.Id,
                        (l, r) => l).SingleOrDefault();
            }
        }

        #region page template
        public bool SavePageTemplate(PageTemplate template)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                if (string.IsNullOrEmpty(context.Set<PageTemplate>().Where(p => p.Code == template.Code)
                    .Select(p => p.Code).SingleOrDefault()))
                {
                    context.Set<PageTemplate>().Add(template);
                }
                else
                {
                    context.Entry(template).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public bool DeleteTemplate(string name)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                PageTemplate template = context.Set<PageTemplate>().Where(p => p.Code == name)
                    .SingleOrDefault();
                if(template == null)
                {
                    return true;
                }
                else
                {
                    context.Entry(template).State = System.Data.Entity.EntityState.Deleted;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public PageTemplate GetPageTemplate(Guid id)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<PageTemplate>().Where(p => p.Id == id)
                    .SingleOrDefault();
            }
        }

        public PageTemplate GetPageTemplate(string name)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<PageTemplate>().Where(p => p.Code == name)
                    .SingleOrDefault();
            }
        }

        public PagedList<PageTemplate> GetPageTemplates(int start, int limit)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                PagedList<PageTemplate> pagedList = new PagedList<PageTemplate>();

                List<PageTemplate> list = context.Set<PageTemplate>()
                    .OrderBy(p => p.Code)
                    .Take(limit)
                    .Skip(start)
                    .ToList();
                int total = context.Set<PageTemplate>()
                    .OrderBy(p => p.Code)
                    .Count();

                pagedList.AddRange(list);
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = total;

                return pagedList;
            }
        }

        public ListResult<PageTemplate> GetPageTemplates(Guid siteId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                List<PageTemplate> list = context.Set<PageTemplate>()
                    .Where(p=>p.SiteId == siteId)
                    .OrderBy(p => p.Code)
                    .ToList();
                return new ListResult<PageTemplate>(list);
            }
        }
        #endregion
    }
}
